home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FM Towns: Free Software Collection 7
/
FM Towns Free Software Collection 7.iso
/
ms_dos
/
dmove86
/
dmmenu.c
< prev
next >
Wrap
Text File
|
1993-11-30
|
7KB
|
399 lines
/*
dmove86 version 1.20a
Copyright (c) 1993 Delmonta
dmmenu.c -- メニューモジュール
*/
#include<stdio.h>
#include<dos.h>
#include"escseq.h"
#include"dmove86.h"
#define RIGHT '\x1c'
#define LEFT '\x1d'
#define UP '\x1e'
#define DOWN '\x1f'
unsigned int Pagenum,Lastnum; /* ページ数・最終ページのエントリ数 */
unsigned int Page,Pos; /* 現在のページ番号とカーソル位置 */
unsigned int Selected; /* 選択され反転表示されている番号 */
struct DIRENTRY far **Dirtbl;
int Changedflag; /* 変更があったかどうかのフラグ */
static void putfilename(p,f) /* 画面にファイル名を表示 */
int p,f; /* f=-1のときは、"::::::::.:::"を表示 */
{
LOCATE( (p%6)*13 , p/6+2);
if (Page*96+p == Selected)
printf("\033[7m");
if ( f==-1)
printf(" ");
else if (Dirtbl[Page*96+p]->filename[0]=='\xe5')
printf(" ::::::::.:::");
else
{
int i;
if (Dirtbl[Page*96+p]->attr & _A_SUBDIR)
printf("\033[32m"); /* ディレクトリは緑 */
else if (Dirtbl[Page*96+p]->attr & _A_VOLID)
printf("\033[35m"); /* ボリュームIDは紫 */
else if (Dirtbl[Page*96+p]->attr & _A_SYSTEM)
printf("\033[31m"); /* システムファイルは赤 */
else
printf("\033[37m"); /* そのほかは白 */
putchar(' ');
for (i=0 ; i<8 ; i++)
putchar(Dirtbl[Page*96+p]->filename[i]);
putchar('.');
for (i=0 ; i<3 ; i++)
putchar(Dirtbl[Page*96+p]->extname[i]);
}
printf(" \033[0;37m");
}
static void putpage() /* ページ表示 */
{
int i;
for (i=0 ; i<96 ; i++)
{
if (Page==Pagenum-1 && i==Lastnum)
for ( ; i<96 ; i++)
putfilename(i,-1);
else
putfilename(i,0);
}
}
void putcursor(void)
{
static int oldx = -1,
oldy = -1;
if (oldx != -1)
{
LOCATE(oldx*13 ,oldy+2);
putchar(' ');
LOCATE(oldx*13+13,oldy+2);
putchar(' ');
}
oldx = Pos%6;
oldy = Pos/6;
LOCATE(oldx*13 ,oldy+2);
putchar('<');
LOCATE(oldx*13+13,oldy+2);
putchar('>');
}
static char movecursor(flag) /* カーソル移動・キー入力 */
int flag; /* カーソル・スペース・ESC以外を受け付けるか */
{
int c;
selectflag(!flag);
LOOP:;
putcursor();
while(kbhit() == 0)
;
c = getch();
if (c == '\3')
endscreen();
if (c == '\x1a')
endscreen();
switch (c)
{
case '6':
case 'D'-0x40: /* ^D */
case RIGHT:
Pos++;
if (Pos==96 || (Page==Pagenum-1 && Pos==Lastnum) )
Pos=0;
break;
case '4':
case 'S'-0x40: /* ^S */
case LEFT:
if (Pos==0)
{
if (Page==Pagenum-1)
Pos = Lastnum-1;
else
Pos = 95;
}
else
Pos--;
break;
case '8':
case 'E'-0x40: /* ^E */
case UP:
if (Pos>=6)
Pos = Pos-6;
break;
case '2':
case 'X'-0x40: /* ^X */
case DOWN:
if (Pos>=96-6 || (Page==Pagenum-1 && Pos+6>=Lastnum) )
; /* Pos>=Lastnum-6では、Lastnum-6<0となって */
else /* Posがunsignedの為正確に判断できない場合有 */
Pos = Pos+6;
break;
case '-':
if (Page>=1)
{
Page--;
putpage();
}
break;
case '+':
if (Page<Pagenum-1)
{
Page++;
if (Page==Pagenum-1 && Pos>=Lastnum)
Pos = Lastnum-1;
putpage();
}
break;
case ' ':
if (Dirtbl[Page*96+Pos]->filename[0]!='.')
return c;
else
dm_errmes("\".\"や\"..\"に対しては操作できません.");
break;
case '\033':
return c;
default:
if (flag)
return c;
break;
}
goto LOOP;
}
int chkflag(void)
{
if (Changedflag==0)
return 1;
printf( "\033[19;1H\033[31m"
"内容の変更があります. よろしいですか(y/n)?"
"\033[37m");
chkflag_loop:;
while (!kbhit())
;
switch(getch())
{
case 'Y':
case 'y':
printf("\033[19;1H\033[2K");
return 1;
case 'N':
case 'n':
printf("\033[19;1H\033[2K");
return 0;
default:
break;
}
goto chkflag_loop;
}
unsigned int dmmenu(dirtbl,dirnum,cursorpos,issubdir)
struct DIRENTRY far **dirtbl;
unsigned int dirnum,cursorpos;
int issubdir;
{
struct DIRENTRY far *d;
unsigned int i;
Dirtbl = dirtbl; /* 下請関数でも値を使えるようにするため */
Selected = -1;
Changedflag = 0;
Pagenum = dirnum/96;
Lastnum = dirnum%96;
if (Lastnum) Pagenum++;
else Lastnum = 96;
if (cursorpos>dirnum) /* cursorposが不正な場合 */
cursorpos = 0;
Page = cursorpos/96;
Pos = cursorpos%96;
putpage();
dmmenu_loop:;
switch(movecursor(1))
{
case 'I':
case 'i':
if ((d=dirtbl[dirnum-1])->filename[0]=='\xe5')
{
for (i=dirnum-1 ; i>Page*96+Pos ; i--)
dirtbl[i] = dirtbl[i-1];
dirtbl[Page*96+Pos] = d;
Changedflag = 1;
putpage();
}
else
putchar('\7');
break;
case 'D':
case 'd':
if ((d=dirtbl[Page*96+Pos])->filename[0]=='\xe5')
{
for (i=Page*96+Pos ; i<dirnum-1 ; i++)
dirtbl[i] = dirtbl[i+1];
dirtbl[dirnum-1] = d;
Changedflag = 1;
putpage();
}
else
putchar('\7');
break;
case ' ':
Selected = Page*96+Pos;
putfilename(Pos,0); /* 反転表示 */
if (movecursor(0)==' ' && Selected!=Page*96+Pos)
{
d = dirtbl[Selected];
dirtbl[Selected] = dirtbl[Page*96+Pos];
dirtbl[Page*96+Pos] = d;
Changedflag = 1;
}
if (Selected/96 == Page) /* 反転を解除 */
{
i = Selected%96;
Selected = -1;
putfilename(i,0);
}
else
Selected = -1;
putfilename(Pos,0);
break;
case '\033':
break;
case 'S':
case 's':
Selected = Page*96+Pos;
putfilename(Pos,0); /* 反転表示 */
printf( "\033[19;1f\033[37m"
"ソート:終点を指定してください\n");
if (movecursor(0)==' ' && Selected!=Page*96+Pos)
{
unsigned int s = Selected,
e = Page*96+Pos;
if (s>e)
{
register unsigned int a = e;
e = s;
s = a;
}
dmsort(dirtbl,s,e);
Changedflag = 1;
}
Selected = -1;
putpage();
break;
case 'R':
case 'r':
dm_errmes("この機能は現時点ではサポートされていません.");
break;
case 'C':
case 'c':
case '\r': /* getch()が返す改行キーのコードは'\n'ではなく'\r' */
if ((dirtbl[Page*96+Pos]->attr & _A_SUBDIR)
&& dirtbl[Page*96+Pos]->filename[0]!='.')
return (Page*96+Pos)*4 + CHGDIR;
break;
case 'O':
case 'o':
return (Page*96+Pos)*4 + ORIGIN;
case 'U':
case 'u':
case '\x08':
if (!issubdir)
dm_errmes("ルートの親ディレクトリはありません.");
else if (chkflag())
return (Page*96+Pos)*4 + UPDIR;
break;
case 'W':
case 'w':
return (Page*96+Pos)*4 + WRTDIR;
case 'Q':
case 'q':
if (chkflag())
endscreen();
default:
putchar('\7');
}
goto dmmenu_loop;
}